/******************************************************************************
 *  TWI (I2C) serial bus functions implementation (master mode)
 ******************************************************************************/
 
#include "twi-utils.h"
 
#define TWI_INIT(addt) TWCR = _BV(TWINT) | _BV(TWEN) | addt
#define TWI_WAIT() while((TWCR & _BV(TWINT)) == 0)
 
int twiStart()
{
    TWI_INIT(_BV(TWSTA));

    TWI_WAIT();
    if(TW_STATUS != TW_START) {
        return 1;
    }
    return 0;
}
 
int twiSelect(unsigned char addr)
{
    TWDR = addr;
    TWI_INIT(0);

    TWI_WAIT();
    if(((addr & TW_WRITE) && TW_STATUS != TW_MT_SLA_ACK) ||
       ((addr & TW_READ) && TW_STATUS != TW_MR_SLA_ACK)) 
    {
        return 1;
    }
    return 0;
}
 
int twiRead(unsigned char* byte, int send_ack)
{
    if(send_ack) {
        TWI_INIT(_BV(TWEA));
    } else {
        TWI_INIT(0);
    }
    TWI_WAIT();
    if((send_ack && TW_STATUS != TW_MR_DATA_ACK) 
       || (!send_ack && TW_STATUS != TW_MR_DATA_NACK))
    {
        return 1;
    }
    *byte = TWDR;
    return 0;
}
 
int twiWrite(unsigned char byte)
{
    TWDR = byte;
    TWI_INIT(0);

    TWI_WAIT();
    if(TW_STATUS != TW_MT_DATA_ACK) {
        return 1;
    }
    return 0;
}
 
void twiStop()
{
    TWI_INIT(_BV(TWSTO));
}